home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / tar-1_11.lha / tar-1.11.2 / msd_dir.c < prev    next >
C/C++ Source or Header  |  1992-09-18  |  5KB  |  230 lines

  1. /*
  2.  * @(#)msd_dir.c 1.4 87/11/06    Public Domain.
  3.  *
  4.  *  A public domain implementation of BSD directory routines for
  5.  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  6.  *  August 1897
  7.  */
  8.  
  9. #include    <sys/types.h>
  10. #include    <sys/stat.h>
  11. #include    "msd_dir.h"
  12. #ifndef __TURBOC__
  13. #include    <malloc.h>
  14. #else
  15. #include    <stdlib.h>
  16. #endif
  17. #include    <string.h>
  18. #include    <dos.h>
  19.  
  20. #ifndef    NULL
  21. # define    NULL    0
  22. #endif /* NULL */
  23.  
  24. #ifndef    MAXPATHLEN
  25. # define    MAXPATHLEN    255
  26. #endif /* MAXPATHLEN */
  27.  
  28. /* attribute stuff */
  29. #define    A_RONLY        0x01
  30. #define    A_HIDDEN    0x02
  31. #define    A_SYSTEM    0x04
  32. #define    A_LABEL        0x08
  33. #define    A_DIR        0x10
  34. #define    A_ARCHIVE    0x20
  35.  
  36. /* dos call values */
  37. #define    DOSI_FINDF    0x4e
  38. #define    DOSI_FINDN    0x4f
  39. #define    DOSI_SDTA    0x1a
  40.  
  41. #define    Newisnull(a, t)        ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  42. /* #define    ATTRIBUTES        (A_DIR | A_HIDDEN | A_SYSTEM) */
  43. #define ATTRIBUTES    (A_RONLY | A_SYSTEM | A_DIR)
  44.  
  45. /* what find first/next calls look use */
  46. typedef struct
  47.   {
  48.     char d_buf[21];
  49.     char d_attribute;
  50.     unsigned short d_time;
  51.     unsigned short d_date;
  52.     long d_size;
  53.     char d_name[13];
  54.   }
  55.  
  56. Dta_buf;
  57.  
  58. static char *getdirent ();
  59. static void mysetdta ();
  60. static void free_dircontents ();
  61.  
  62. static Dta_buf dtabuf;
  63. static Dta_buf *dtapnt = &dtabuf;
  64. static union REGS reg, nreg;
  65.  
  66. #if    defined(M_I86LM)
  67. static struct SREGS sreg;
  68. #endif
  69.  
  70. DIR *
  71. opendir (name)
  72.      char *name;
  73. {
  74.   struct stat statb;
  75.   DIR *dirp;
  76.   char c;
  77.   char *s;
  78.   struct _dircontents *dp;
  79.   char nbuf[MAXPATHLEN + 1];
  80.  
  81.   if (stat (name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  82.     return (DIR *) NULL;
  83.   if (Newisnull (dirp, DIR))
  84.     return (DIR *) NULL;
  85.   if (*name && (c = name[strlen (name) - 1]) != '\\' && c != '/')
  86.     (void) strcat (strcpy (nbuf, name), "\\*.*");
  87.   else
  88.     (void) strcat (strcpy (nbuf, name), "*.*");
  89.   dirp->dd_loc = 0;
  90.   mysetdta ();
  91.   dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  92.   if ((s = getdirent (nbuf)) == (char *) NULL)
  93.     return dirp;
  94.   do
  95.     {
  96.       if (Newisnull (dp, struct _dircontents) || (dp->_d_entry =
  97.              malloc ((unsigned) (strlen (s) + 1))) == (char *) NULL)
  98.     {
  99.       if (dp)
  100.         free ((char *) dp);
  101.       free_dircontents (dirp->dd_contents);
  102.       return (DIR *) NULL;
  103.     }
  104.       if (dirp->dd_contents)
  105.     dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  106.       else
  107.     dirp->dd_contents = dirp->dd_cp = dp;
  108.       (void) strcpy (dp->_d_entry, s);
  109.       dp->_d_next = (struct _dircontents *) NULL;
  110.     }
  111.   while ((s = getdirent ((char *) NULL)) != (char *) NULL);
  112.   dirp->dd_cp = dirp->dd_contents;
  113.  
  114.   return dirp;
  115. }
  116.  
  117. void
  118. closedir (dirp)
  119.      DIR *dirp;
  120. {
  121.   free_dircontents (dirp->dd_contents);
  122.   free ((char *) dirp);
  123. }
  124.  
  125. struct dirent *
  126. readdir (dirp)
  127.      DIR *dirp;
  128. {
  129.   static struct dirent dp;
  130.  
  131.   if (dirp->dd_cp == (struct _dircontents *) NULL)
  132.     return (struct dirent *) NULL;
  133.   dp.d_namlen = dp.d_reclen =
  134.     strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry));
  135.   strlwr (dp.d_name);        /* JF */
  136.   dp.d_ino = 0;
  137.   dirp->dd_cp = dirp->dd_cp->_d_next;
  138.   dirp->dd_loc++;
  139.  
  140.   return &dp;
  141. }
  142.  
  143. void
  144. seekdir (dirp, off)
  145.      DIR *dirp;
  146.      long off;
  147. {
  148.   long i = off;
  149.   struct _dircontents *dp;
  150.  
  151.   if (off < 0)
  152.     return;
  153.   for (dp = dirp->dd_contents; --i >= 0 && dp; dp = dp->_d_next)
  154.     ;
  155.   dirp->dd_loc = off - (i + 1);
  156.   dirp->dd_cp = dp;
  157. }
  158.  
  159. long
  160. telldir (dirp)
  161.      DIR *dirp;
  162. {
  163.   return dirp->dd_loc;
  164. }
  165.  
  166. static void
  167. free_dircontents (dp)
  168.      struct _dircontents *dp;
  169. {
  170.   struct _dircontents *odp;
  171.  
  172.   while (dp)
  173.     {
  174.       if (dp->_d_entry)
  175.     free (dp->_d_entry);
  176.       dp = (odp = dp)->_d_next;
  177.       free ((char *) odp);
  178.     }
  179. }
  180.  
  181. static char *
  182. getdirent (dir)
  183.      char *dir;
  184. {
  185.   if (dir != (char *) NULL)
  186.     {                /* get first entry */
  187.       reg.h.ah = DOSI_FINDF;
  188.       reg.h.cl = ATTRIBUTES;
  189. #if    defined(M_I86LM)
  190.       reg.x.dx = FP_OFF (dir);
  191.       sreg.ds = FP_SEG (dir);
  192. #else
  193.       reg.x.dx = (unsigned) dir;
  194. #endif
  195.     }
  196.   else
  197.     {                /* get next entry */
  198.       reg.h.ah = DOSI_FINDN;
  199. #if    defined(M_I86LM)
  200.       reg.x.dx = FP_OFF (dtapnt);
  201.       sreg.ds = FP_SEG (dtapnt);
  202. #else
  203.       reg.x.dx = (unsigned) dtapnt;
  204. #endif
  205.     }
  206. #if    defined(M_I86LM)
  207.   intdosx (®, &nreg, &sreg);
  208. #else
  209.   intdos (®, &nreg);
  210. #endif
  211.   if (nreg.x.cflag)
  212.     return (char *) NULL;
  213.  
  214.   return dtabuf.d_name;
  215. }
  216.  
  217. static void
  218. mysetdta ()
  219. {
  220.   reg.h.ah = DOSI_SDTA;
  221. #if    defined(M_I86LM)
  222.   reg.x.dx = FP_OFF (dtapnt);
  223.   sreg.ds = FP_SEG (dtapnt);
  224.   intdosx (®, &nreg, &sreg);
  225. #else
  226.   reg.x.dx = (int) dtapnt;
  227.   intdos (®, &nreg);
  228. #endif
  229. }
  230.